//
// Created by francklinson on 2021/10/8 AT 10:18.
//
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <algorithm>
#include <functional>
#include <climits>
#include <string>

using namespace std;

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        // hash表记录每个长度为10的序列  重复出现时放入结果中
        vector<string> ans;
        if (s.size() <= 10)
            return ans;
        unordered_map<string, int> substrCounter;
        for (int i = 0; i <= s.size() - 10; ++i) {
            string curStr = s.substr(i, 10);
            substrCounter[curStr]++;
            if (substrCounter[curStr] == 2)
                ans.push_back(curStr);
        }
        return ans;
    }
};
class Solution2 {
    const int L = 10;
    unordered_map<char, int> bin = {{'A', 0}, {'C', 1}, {'G', 2}, {'T', 3}};
public:
    vector<string> findRepeatedDnaSequences(string s) {
        vector<string> ans;
        int n = s.length();
        if (n <= L) {
            return ans;
        }
        int x = 0;
        for (int i = 0; i < L - 1; ++i) {
            x = (x << 2) | bin[s[i]];
        }
        unordered_map<int, int> cnt;
        for (int i = 0; i <= n - L; ++i) {
            x = ((x << 2) | bin[s[i + L - 1]]) & ((1 << (L * 2)) - 1);
            if (++cnt[x] == 2) {
                ans.push_back(s.substr(i, L));
            }
        }
        return ans;
    }
};

int main() {
    Solution2 solution;
    vector<string> ans = solution.findRepeatedDnaSequences("AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT");
//    vector<string> ans = solution.findRepeatedDnaSequences("AAAAAAAAAAA");
    for (string &x: ans)
        cout << x << endl;
    return 0;
}

